package com.gitee.wsl.func.filter.bloomfilter

import com.gitee.wsl.func.filter.bloomfilter.api.IndexExtractor
import com.gitee.wsl.func.filter.bloomfilter.bean.Shape
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue


/**
 * Tests for the [SparseBloomFilter].
 */
class SparseBloomFilterTest : AbstractBloomFilterTest<SparseBloomFilter>() {
    protected override fun createEmptyFilter(shape: Shape): SparseBloomFilter {
        return SparseBloomFilter(shape)
    }

    @Test
    fun testBitMapExtractorEdgeCases() {
        var values = intArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 65, 66, 67, 68, 69, 70, 71)
        var bf = createFilter(testShape, IndexExtractor.fromIndexArray(*values))

        // verify exit early before bitmap boundary
        val passes = IntArray(1)
        assertFalse(bf.processBitMaps({ l ->
            passes[0]++
            false
        }))
        assertEquals(1, passes[0])

        // verify exit early at bitmap boundary
        bf = createFilter(testShape, IndexExtractor.fromIndexArray(*values))
        passes[0] = 0
        assertFalse(bf.processBitMaps({ l ->
            val result = passes[0] == 0
            if (result) {
                passes[0]++
            }
            result
        }))
        assertEquals(1, passes[0])

        // verify add extra if all values in first bitmap
        values = intArrayOf(1, 2, 3, 4)
        bf = createFilter(testShape, IndexExtractor.fromIndexArray(*values))
        passes[0] = 0
        assertTrue(bf.processBitMaps({ l ->
            passes[0]++
            true
        }))
        assertEquals(2, passes[0])

        // verify exit early if all values in first bitmap and predicate returns false
        // on 2nd block
        values = intArrayOf(1, 2, 3, 4)
        bf = createFilter(testShape, IndexExtractor.fromIndexArray(*values))
        passes[0] = 0
        assertFalse(bf.processBitMaps({ l ->
            val result = passes[0] == 0
            if (result) {
                passes[0]++
            }
            result
        }))
        assertEquals(1, passes[0])
    }

    @Test
    fun testBloomFilterBasedMergeEdgeCases() {
        val bf1 = createEmptyFilter(testShape)
        val bf2 = SimpleBloomFilter(testShape)
        bf2.merge(TestingHashers.FROM1)
        bf1.merge(bf2)
        assertTrue(bf2.processBitMapPairs(bf1, { x, y -> x == y }))
    }
}
